package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"reflect"
	"strings"
)

func closeResource(o interface{}) {
	rType := reflect.TypeOf(o)
	if rType.Kind() != reflect.Pointer {
		fmt.Println("输入类型不可关闭 1")
	}
	rType = rType.Elem()
	if rType.Kind() != reflect.Interface {
		fmt.Println("输入类型不可关闭 2")
		return
	}
	rValue := reflect.ValueOf(o)
	closeMethod := rValue.Elem().MethodByName("Close")
	if closeMethod.IsZero() {
		fmt.Println("未发现Close方法")
		return
	}
	closeResult := closeMethod.Call(nil)
	if closeResult[0].IsNil() {
		fmt.Println(rType.Name(), "关闭成功")
	} else {
		err := closeResult[0].Interface()
		fmt.Println("关闭失败", err)
	}
}

func process(conn net.Conn) {
	for {
		bytebuffer := make([]byte, 1024)
		n, err := conn.Read(bytebuffer)
		if err != nil {
			fmt.Println("从服务端接收消息失败", err)
			continue
		}
		fmt.Println("从服务段", conn.RemoteAddr().String(), "接收到消息：", string(bytebuffer[:n]))
	}
}

func main() {
	ln, err := net.Dial("tcp", "127.0.0.1:8888")
	if err != nil {
		fmt.Println("和服务端建立链接失败")
		return
	}
	defer closeResource(&ln)
	go process(ln)
	for {
		fmt.Println("输入要发送的消息，推出请输入exit：")
		reader := bufio.NewReader(os.Stdin)
		readString, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("输入异常，", err)
			continue
		}
		if strings.Contains(readString, "exit") {
			return
		}
		_, err = ln.Write([]byte(readString))
		if err != nil {
			fmt.Println("发送数据失败，", err)
			continue
		}
	}
}
